﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using IPMsgExpections;
using CommonUtility;
using System.Text;

namespace MessageCenter
{
    public class MessageModel
    {
        #region fields
        //版本号
        private uint version;

        //包编号
        private uint indexPack;

        //用户名
        private string userName;

        //主机名
        private string hostName;

        //命令字
        private uint commandWords;

        //附加信息
        private string attachMessages;
        #endregion

        #region Properties
        //获取或者设置版本号
        public uint Version
        {
            get { return version; }
            set { version = value; }
        }

        //获取或者设置包编号
        public uint IndexPack
        {
            get { return indexPack; }
            set { indexPack = value; }
        }

        //获取或者设置用户名
        public string UserName
        {
            get { return userName; }
            set { userName = value; }
        }

        //获取或者设置主机名
        public string HostName
        {
            get { return hostName; }
            set { hostName = value; }
        }

        //获取或者设置命令字
        public uint CommandWords
        {
            get { return commandWords; }
            set { commandWords = value; }
        }

        //获取或者设置附加信息
        public string AttachMessages
        {
            get { return attachMessages; }
            set { attachMessages = value; }
        }
        #endregion

        #region Constructor
        internal MessageModel()
        {
        }

        //构造函数
        public MessageModel(string userName, string hostName, uint indexPackage)
        {
            this.version = ConstWords.IPMSG_VERSION;
            this.userName = userName;
            this.hostName = hostName;
            this.indexPack = indexPackage;
        }

        internal MessageModel(
            uint version,
            uint indexPack,
            string userName,
            string hostName,
            string attachMessages)
        {
            this.version = version;
            this.indexPack = indexPack;
            this.userName = userName;
            this.hostName = hostName;
            this.attachMessages = attachMessages;
        }
        #endregion

        #region Public funcs

        /// <summary>
        /// 将收到的数据包格式化为消息格式
        /// </summary>
        /// <param name="receiveBytes">收到的数据包(byte数组)</param>
        /// <returns>消息格式</returns>
        public static MessageModel DecodingMessage(byte[] receiveBytes)
        {
            //按照gb2312编码将字节数组转化为字符串
            string receiveString = Gb2312Encoding.GetString(receiveBytes);
            //按照分隔符":"分隔字符串
            string[] splitStrings = receiveString.Split(ConstWords.IPMSG_SEPARATOR.ToCharArray()[0]);
            //判断子字符串数目
            if (splitStrings.Length < 6)
            {
                throw new MessageExpection("解析接收到的消息有误：按照':'分隔符分隔后的子字符串小于6!");
            }

            uint commondWordTmp = 0;
            uint versionTmp = 0;
            uint indexPackTmp = 0;
            string userNameTmp = splitStrings[2];
            string hostNameTmp = splitStrings[3];
            //可能有问题，发送文件时文件名中有可能有":"
            string attachMessagesTmp = splitStrings[5];

            try
            {
                commondWordTmp = Convert.ToUInt32(splitStrings[4]);
            }
            catch (Exception ex)
            {
                throw new MessageExpection("解析接收到的消息有误：命令字错误(无法转化为数字)!", ex);
            }

            try
            {
                versionTmp = Convert.ToUInt32(splitStrings[0]);
            }
            catch (Exception ex)
            {
                throw new MessageExpection("解析接收到的消息有误：版本错误(无法转化为数字)!", ex);
            }

            try
            {
                indexPackTmp = Convert.ToUInt32(splitStrings[1]);
            }
            catch (Exception ex)
            {
                throw new MessageExpection("解析接收到的消息有误：包序号错误(无法转化为数字)!", ex);
            }

            uint commonCommondwords = commondWordTmp & (uint)0xff;
            switch (commonCommondwords)
            {
                case ConstWords.CommonCommand.IPMSG_NOOPERATION:
                    return new MessageNoopration(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                case ConstWords.CommonCommand.IPMSG_BR_ENTRY:
                    return new MessageBrEntry(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                case ConstWords.CommonCommand.IPMSG_BR_EXIT:
                    return new MessageBrExit(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                case ConstWords.CommonCommand.IPMSG_ANSENTRY:
                    return new MessageAnsEntry(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                case ConstWords.CommonCommand.IPMSG_SENDMSG:
                    return new MessageSendMsg(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                case ConstWords.CommonCommand.IPMSG_RECVMSG:
                    return new MessageRecvMsg(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                case ConstWords.CommonCommand.IPMSG_READMSG:
                    return new MessageReadMsg(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                case ConstWords.CommonCommand.IPMSG_GETFILEDATA:
                    return new MessageGetFileData(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                case ConstWords.CommonCommand.IPMSG_RELEASEFILES:
                    return new MessageReleaseFiles(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                case ConstWords.CommonCommand.IPMSG_GETDIRFILES:
                    return new MessageGetDirFiles(
                        versionTmp,
                        indexPackTmp,
                        userNameTmp,
                        hostNameTmp,
                        commondWordTmp,
                        attachMessagesTmp);
                default:
                    return null;
            }
        }

        public byte[] EncodingMessage()
        {
            string messageToEncode = ConstWords.IPMSG_VERSION //version
                + ConstWords.IPMSG_SEPARATOR                  //:   
                + this.indexPack                              //包序号
                + ConstWords.IPMSG_SEPARATOR                  //:
                + this.userName                               //用户名
                + ConstWords.IPMSG_SEPARATOR                  //:
                + this.hostName                               //主机名
                + ConstWords.IPMSG_SEPARATOR                  //:
                + this.commandWords                           //命令字
                + ConstWords.IPMSG_SEPARATOR                  //:
                + this.attachMessages;                        //附加消息

            return Gb2312Encoding.GetBytes(messageToEncode);
        }
        #endregion
    }
}
